package com.shujia;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;

import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaStringObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.io.Text;

import static org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory.*;

public class MyLenFunc extends GenericUDF {
    /*
        select mylen('1234') => 4

        initialize函数中需要对当前的 函数调用时进行做相关的实例化检查工作
            比如 对于数据的类型 参数的个数

        create temporary function mylen as 'com.shujia.MyLenFunc';
     */

    /**
     *
     * @param arguments 表示传入的参数报装的对象数组
     * @return
     * @throws UDFArgumentException
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        // 如果长度不为1 那么说明传入参数存在错误
        if (arguments.length != 1) {
            throw new UDFArgumentLengthException("当前函数仅支持一个字符串参数");
        }

        // 对类型进行判断

        ObjectInspector argument = arguments[0];
        // ObjectInspector.Category.PRIMITIVE 表示的是HIVE中的普通类型 包括 String int date ...
        if (!argument.getCategory().equals(ObjectInspector.Category.PRIMITIVE)) {
            throw new UDFArgumentTypeException(0,"您提供的类型有误");
        }

        // ObjectInspector 表示为一个对象的检查器，那么在该函数中进行返回表示
        //     对于函数调用时，返回的结果类型 => 在该案例中返回值类型为String
        //     JavaStringObjectInspector 是 ObjectInspector接口的子实现类
        //        那么在该处可以直接返回一个JavaStringObjectInspector对象即可
//        new JavaStringObjectInspector()
//        ObjectInspectorFactory.
        // PrimitiveObjectInspectorFactory 表示所有的普通类型对象的构造工厂
//        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     *  evaluate 中可以对数据进行按行计算 并返回结果
     * @param arguments  传入的参数 需要使用get函数获取对象 再进行强制转换
     *
     * @return
     * @throws HiveException
     */
    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
//        String argStr =  (String)arguments[0].get();
        Text argText = (Text)arguments[0].get();
        String argStr = argText.toString();

        return argStr.length();
    }

    @Override
    public String getDisplayString(String[] children) {
        return "getDisplayString..";
    }


}
